#include "../Header/Matrix4.h"
#define _USE_MATH_DEFINES
#include <cmath>

/*
This function sets the matrix Result to the identity matrix
*/
Matrix4 Matrix4Identity()
{
	return Matrix4(
		1,0,0,0,
		0,1,0,0,
		0,0,1,0,
		0,0,0,1);
}

// ---------------------------------------------------------------------------

/*
This functions calculated the transpose matrix of Mtx and saves it in Result
*/
Matrix4 Matrix4Transpose(const Matrix4& Mtx)
{
	Matrix4 result;

	// Row i of result = Column i of original
	for (int i=0;  i<3;  i++) 
	{
		for (int j=0;  j<3;  j++) 
		{
			result.m[j][i] = Mtx.m[i][j]; 
		}
	}

	return result;
}

// ---------------------------------------------------------------------------

/*
This function creates a translation matrix from x & y and saves it in Result
*/
Matrix4 Matrix4Translate(float x, float y, float z)
{
	/***************
	*  1  0  0 tx *
	*  0  1  0 ty *
	*  0  0  1 tz *
	*  0  0  0  1 *
	***************/
	Matrix4 result;
	D3DXMatrixTranslation(&result,x,y,z);

	return result;
}

// ---------------------------------------------------------------------------

/*
This function creates a scaling matrix from x & y and saves it in Result
*/
Matrix4 Matrix4Scale(float x, float y, float z)
{
	/***************
	* sx  0  0  0 *
	*  0 sy  0  0 *
	*  0  0 sz  0 *
	*  0  0  0  1 *
	***************/
	Matrix4 result;
	D3DXMatrixScaling(&result,x,y,z);

	return result;
}

// ---------------------------------------------------------------------------

/*
This matrix creates a rotation matrix from "Angle" whose value is in degrees.
Save the resultant matrix in Result
*/
Matrix4 Matrix4RotZDeg(float Angle)
{
	// Convert degrees to radians and call other rotation function.
	float rad_angle = (Angle / 360.0f) * (2*M_PI );
	return Matrix4RotZRad(rad_angle);
}

// ---------------------------------------------------------------------------

/*
This matrix creates a rotation matrix from "Angle" whose value is in radians.
Save the resultant matrix in Result
*/
Matrix4 Matrix4RotZRad(float Angle)
{
	/*******************
	* cos -sin  0   0 *
	* sin  cos  0   0 *
	*  0    0   1   0 *
	*  0    0   0   1 *
	*******************/
	Matrix4 result;
	D3DXMatrixRotationZ(&result,Angle);

	return result;
}

// ---------------------------------------------------------------------------

/*
This function multiplies the matrix Mtx with the vector Vec and saves the result in Result
Result = Mtx * Vec
*/
Vector2D Matrix4MultVec2(const Matrix4& Mtx, Vector2D Vec)
{
	Vector4D result;

	// Multiply Mtx * Vec to get the result vector. (Assume w = 1 for Vec)
	D3DXVec2Transform(&result,&Vec,&Mtx);

	return Vector2D(result);
}

Matrix4 Matrix4Inverse(const Matrix4& Mtx)
{
	Matrix4 result;
	float det;

	D3DXMatrixInverse(&result,&det,&Mtx);

	return result;
}
